package com.gmcloud.common.security.config;

import com.gmcloud.common.security.config.oauth2.PermitAllUrlProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.security.web.SecurityFilterChain;


/**
 * @author zl.sir
 * @version 1.0
 * @since 2022/8/17 1:13
 * 服务器认证授权
 */
@EnableWebSecurity
public class GmResourceServerConfiguration {

    private final PermitAllUrlProperties permitAllUrl;

    private final OpaqueTokenIntrospector customOpaqueTokenIntrospector;

    protected final ResourceAuthExceptionEntryPoint resourceAuthExceptionEntryPoint;

    private final GmBearerTokenExtractor gmBearerTokenExtractor;


    public GmResourceServerConfiguration(PermitAllUrlProperties permitAllUrl, OpaqueTokenIntrospector customOpaqueTokenIntrospector, ResourceAuthExceptionEntryPoint resourceAuthExceptionEntryPoint, GmBearerTokenExtractor gmBearerTokenExtractor) {
        this.permitAllUrl = permitAllUrl;
        this.customOpaqueTokenIntrospector = customOpaqueTokenIntrospector;
        this.resourceAuthExceptionEntryPoint = resourceAuthExceptionEntryPoint;
        this.gmBearerTokenExtractor = gmBearerTokenExtractor;
    }


    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        http.authorizeRequests(authorizeRequests -> authorizeRequests
                        .antMatchers(HttpMethod.GET, permitAllUrl.getIgnore().getGet().toArray(String[]::new)).permitAll()
                        .antMatchers(HttpMethod.POST, permitAllUrl.getIgnore().getPost().toArray(String[]::new)).permitAll()
                        .antMatchers(HttpMethod.DELETE, permitAllUrl.getIgnore().getDelete().toArray(String[]::new)).permitAll()
                        .antMatchers(HttpMethod.PUT, permitAllUrl.getIgnore().getPut().toArray(String[]::new)).permitAll()
                        .antMatchers(HttpMethod.HEAD, permitAllUrl.getIgnore().getHead().toArray(String[]::new)).permitAll()
                        .antMatchers(HttpMethod.PATCH, permitAllUrl.getIgnore().getPatch().toArray(String[]::new)).permitAll()
                        .antMatchers(HttpMethod.OPTIONS, permitAllUrl.getIgnore().getOptions().toArray(String[]::new)).permitAll()
                        .antMatchers(HttpMethod.TRACE, permitAllUrl.getIgnore().getTrace().toArray(String[]::new)).permitAll()
                        .antMatchers(permitAllUrl.getIgnore().getPattern().toArray(String[]::new)).permitAll()
                        .anyRequest()
                        .authenticated())
                .oauth2ResourceServer(
                        oauth2 -> oauth2.opaqueToken(token -> token.introspector(customOpaqueTokenIntrospector))
                                .authenticationEntryPoint(resourceAuthExceptionEntryPoint)
                                .bearerTokenResolver(gmBearerTokenExtractor))
                .headers().frameOptions().disable().and().csrf().disable();

        return http.build();
    }


}
